package com.gtm.controller;

import com.alibaba.fastjson.JSONObject;
import com.gtm.model.User;
import com.gtm.repository.UserRepository;
import com.gtm.service.BaseService;
import com.gtm.service.TopicService;
import com.gtm.service.UserServicce;
import com.mongodb.BasicDBObject;
import com.mongodb.gridfs.GridFSDBFile;
import com.mongodb.util.JSON;
import io.swagger.annotations.*;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.InputStreamSource;
import org.springframework.core.io.Resource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.CacheControl;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.mail.MessagingException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Created by dell on 2017/10/25.
 */

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private TopicService topicService;
    @Autowired
    private UserServicce userServicce;

//    @Autowired
//    BaseService bs;

    @ApiOperation(value="创建用户", notes="创建一个测试对象",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "username",value = "学号或教师号"),
            @ApiImplicitParam(name = "pwd",value = "密码"),
            @ApiImplicitParam(name = "realname",value = "姓名"),
            @ApiImplicitParam(name = "type",value = "类型")
    } )
    @RequestMapping("/save")
    User save(String username,String pwd,String realname,Byte type){
        User user=new User();
        user.setRealname("胡哲伟");
        user.setPasswd("123456");
        user.setUsername("1512190229");
        user.setType((byte)0);
        BasicDBObject detail=new BasicDBObject();
        detail.put("email","1214412549@qq.com");
        detail.put("tel","15967173981");
        detail.put("sex","男");
        user.setDetail(detail);
        return userServicce.add(user);
    }

    @ApiOperation(value="登录", httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "user",value = "json类型的用户名密码",dataType = "String",paramType = "body"),
    } )
    @RequestMapping("/login")
    User login(@RequestBody String user){
        JSONObject us= com.alibaba.fastjson.JSON.parseObject(user);
        String username=us.getString("username");
        String password=us.getString("password");
        return userServicce.findByUsernamePassword(username,password);
    }

    @ApiOperation(value="ajax登录", notes="赋予权限",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "user",value = "json类型的用户名密码",dataType = "String"),
    } )
    @ApiResponses({
            @ApiResponse(code = 200,message = "成功"),
            @ApiResponse(code = 500,message = "失败")
    })
    @RequestMapping(value="/ajaxLogin",method=RequestMethod.POST)
    public Map<String,Object> submitLogin(@RequestBody String user) {
        JSONObject us= com.alibaba.fastjson.JSON.parseObject(user);
        String username=us.getString("username");
        String password=us.getString("password");
        Map<String, Object> resultMap = new LinkedHashMap<String, Object>();
        try {
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            Subject currentUser = SecurityUtils.getSubject();
            currentUser.login(token);
            User u=userServicce.findByUsernamePassword(username,password);
            resultMap.put("user",u);
            resultMap.put("status", 200);
            resultMap.put("message", "登录成功");
        } catch (Exception e) {
            resultMap.put("status", 500);
            resultMap.put("message", e.getMessage());
        }
        return resultMap;
    }


    @ApiOperation(value="ajax退出", notes="失去权限",httpMethod = "GET")
    @RequestMapping(value="/logout",method =RequestMethod.GET)
    @ResponseBody
    public Map<String,Object> logout(){
        Map<String, Object> resultMap = new LinkedHashMap<String, Object>();
        try {
            //退出
            SecurityUtils.getSubject().logout();
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
        return resultMap;
    }


    //查询所有老师   导师和可以出题,所以type=1
    @ApiOperation(value="查询所有老师", notes="通过type寻找user  type为1",httpMethod = "GET")
    @RequestMapping("/findTeacher")
    List<User> findTeacher(){
        return userServicce.findByType();
    }

    @ApiOperation(value="更新用户", notes="更新",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "user",value = "一个学生的json",dataType = "String"),
    } )
    @RequestMapping("/updateUser")
    void updateUser(@RequestBody String user){
        JSONObject us= com.alibaba.fastjson.JSON.parseObject(user);
        //System.out.println(us.toString());
        String email=us.getString("email");
        String password=us.getString("password");
        String phone=us.getString("phone");
        String id=us.getString("id");
        String sex=us.getString("sex");
        userServicce.updateUser(email,password,phone,id,sex);
    }

    @ApiOperation(value="更新用户", notes="更新",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "email",value = "email",dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "password",value = "password",dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "phone",value = "phone",dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "office",value = "office",dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "level",value = "office",dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "direction",value = "direction",dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "sex",value = "sex",dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "sign",value = "sign",dataType = "MultipartFile",paramType = "query"),
            @ApiImplicitParam(name = "id",value = "userid",dataType = "String",paramType = "path"),
    } )
    @RequestMapping("/updateUserWithSign/{id}")
    void updateUserWithSign(@RequestParam("email")String email, @RequestParam("password")String password, @RequestParam("phone")String phone,
                            @RequestParam("office")String office, @RequestParam("level")String level, @RequestParam("direction")String direction,
                            @RequestParam("sex")String sex, @RequestParam("sign")MultipartFile sign, @PathVariable String id) throws IOException {
        userServicce.updateUserWithSign(id,email,password,phone,office,level,direction,sex,sign);

    }


//    @RequestMapping("/getFile/{resourceId}")
//    public ResponseEntity<Resource> getFile(@PathVariable String resourceId) throws UnsupportedEncodingException {
//        GridFSDBFile file = bs.getFile(resourceId);
//
//        String filename = "inline; filename=" + URLEncoder.encode(file.getFilename(), "UTF-8");
//        return ResponseEntity.ok().header(HttpHeaders.CONTENT_TYPE, file.getContentType())
//                .header(HttpHeaders.CONTENT_ENCODING, "UTF-8").header(HttpHeaders.CONTENT_DISPOSITION, filename)
//                .cacheControl(CacheControl.maxAge(7, TimeUnit.DAYS))
//                .body(new InputStreamResource(file.getInputStream()));
//    }

    @ApiOperation(value="getFile", notes="根据id利用gridfs从mongodb中获取file",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "resourceId",value = "资源id",dataType = "String",paramType = "path"),
    } )
    @RequestMapping("/getFile/{resourceId}")
    public ResponseEntity<Resource> getFile(@PathVariable String resourceId) throws UnsupportedEncodingException {
        GridFSDBFile file = userServicce.getFile(resourceId);

        String filename = "inline; filename=" + URLEncoder.encode(file.getFilename(), "UTF-8");
        return ResponseEntity.ok().header(HttpHeaders.CONTENT_TYPE, file.getContentType())
                .header(HttpHeaders.CONTENT_ENCODING, "UTF-8").header(HttpHeaders.CONTENT_DISPOSITION, filename)
                .cacheControl(CacheControl.maxAge(7, TimeUnit.DAYS))
                .body(new InputStreamResource(file.getInputStream()));
    }

    @ApiOperation(value="下载文件", notes="根据id利用gridfs从mongodb中获取file",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "resourceId",value = "资源id",dataType = "String",paramType = "path"),
    } )
    @RequestMapping("/downFile/{resourceId}")
    public ResponseEntity<Resource> downFile(@PathVariable String resourceId) throws UnsupportedEncodingException {
        GridFSDBFile file = userServicce.getFile(resourceId);
        String filename = "inline; filename=" + URLEncoder.encode(file.getFilename(), "UTF-8");
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Content-Disposition", String.format("attachment; filename=\"%s\"", filename));
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        return ResponseEntity
                .ok()
                .headers(headers)
                .header(HttpHeaders.CONTENT_TYPE, file.getContentType())
                .header(HttpHeaders.CONTENT_ENCODING, "UTF-8")
                .cacheControl(CacheControl.maxAge(7, TimeUnit.DAYS))
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(new InputStreamResource(file.getInputStream()));
    }


    //找回密码时，填入用户名，邮箱判断是否匹配
    @ApiOperation(value="checkUser", notes="找回密码时，填入用户名，邮箱判断是否匹配",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "user",value = "user的用户名 邮箱",dataType = "String"),
    } )
    @RequestMapping("/checkuser")
    User checkUser(@RequestBody String user){
        JSONObject us= com.alibaba.fastjson.JSON.parseObject(user);
        String username=us.getString("username");
        String email=us.getString("email");
        return userServicce.findByUsernameEmail(username,email);
    }

    @ApiOperation(value="findUser", notes="根据id查找用户",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "id",value = "userId",dataType = "String",paramType = "path"),
    } )
    @RequestMapping("/findUser/{id}")
    User findUser(@PathVariable String id){
        return userServicce.findById(id);

    }

    @ApiOperation(value="delTopic", notes="删除用户中的topic",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "id",value = "userId",dataType = "String",paramType = "path"),
    } )
    @RequestMapping("/delTopic/{id}")
    void delTopic(@PathVariable String id){
        userServicce.deltopic(id);
    }

    @ApiOperation(value="listStudent", notes="列出老师下的学生",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "tid",value = "老师id",dataType = "String",paramType = "path"),
            @ApiImplicitParam(name = "topicChose",value = "课题id",dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "stuName",value = "学生名字",dataType = "String",paramType = "query"),
    } )
    @RequestMapping("/listStudent/{tid}")
    List<User> listStudent(@PathVariable String tid,@RequestParam(value = "topicChose",required = false)String topicChose,@RequestParam(value = "stuName",required = false)String stuName){
        System.out.println(topicChose+stuName);
        return userServicce.listStudent(tid,topicChose,stuName);
    }


    @ApiOperation(value="findUser", notes="根据id查找用户",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "id",value = "userId",dataType = "String",paramType = "path"),
    } )
    @RequestMapping("/find/{id}")
    User find(@PathVariable String id){
        return userRepository.findOne(id);
    }

    @ApiOperation(value="findStudent", notes="查找学生",httpMethod = "POST")
    @RequestMapping("/findStudent")
    List<User> findUser(){
        return userServicce.findStu();
    }


    @ApiOperation(value="resetPwd", notes="重置密码发送邮箱",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "username",value = "用户名",dataType = "String",paramType = "path"),
    } )
    @RequestMapping("/resetPwd/{username}")
    User resetPwd(@PathVariable String username) throws MessagingException {
        return userServicce.resetPassword(username);
    }

    @ApiOperation(value="findByState", notes="查找对应状态的用户",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "state",value = "状态",dataType = "String",paramType = "path"),
    } )
    @RequestMapping("/findByState/{state}")
    List<User> findByState(@PathVariable String state){
        return userServicce.findByState(state);
    }

    @ApiOperation(value="findByStateIn", notes="查找属于对应状态列表的用户",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "state",value = "状态",dataType = "List<String>",paramType = "path"),
    } )
    @RequestMapping("/findByStateIn/{state}")
    List<User> findByStateIn(@PathVariable List<String> state){
        return userServicce.findByStateIn(state);
    }

    @ApiOperation(value="findByAddStateIn", notes="查找addtional中属于对应状态列表的用户",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "state",value = "状态",dataType = "String",paramType = "path"),
            @ApiImplicitParam(name = "size",value = "每页条数",dataType = "String",paramType = "path"),
            @ApiImplicitParam(name = "page",value = "第几页",dataType = "String",paramType = "path"),
            @ApiImplicitParam(name = "searchKey",value = "查询条件",dataType = "String",paramType = "path"),
    } )
    @RequestMapping({"/findByAddStateIn/{state}/{size}/{page}","/findByAddStateIn/{state}/{size}/{page}/{searchKey}"})
    Page<User> findByAddStateIn(@PathVariable int size,@PathVariable int page,@PathVariable String state,@PathVariable(required = false) String searchKey){
        return userServicce.findByAddSta0teIn(new PageRequest(page,size, Sort.Direction.DESC,"topicId"),state,searchKey);
        //user.setAdditionalData("state","PROPOSAL_PENDING");
    }

    @ApiOperation(value="findByNotOfStu", notes="根据stuid查找非该学生的导师列表",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "stuId",value = "学生id",dataType = "String",paramType = "path"),
    } )
    @RequestMapping({"/findByNotOfStu/{stuId}"})
    List<User> findByNotOfStu(@PathVariable String stuId){
        return userServicce.findByNotOfStu(stuId);
        //user.setAdditionalData("state","PROPOSAL_PENDING");
    }

    @ApiOperation(value="stuUploadThesis", notes="学生上传论文",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "stuId",value = "学生id",dataType = "String",paramType = "path"),
            @ApiImplicitParam(name = "ThesisFile",value = "论文",dataType = "MultipartFile",paramType = "query"),
    } )
    @RequestMapping({"/stuUploadThesis/{stuId}"})
    User findByNotOfStu(@PathVariable String stuId,@RequestParam("ThesisFile")MultipartFile ThesisFile) throws IOException {
        return userServicce.stuUploadThesis(stuId,ThesisFile);
    }

    @ApiOperation(value="auditThesis", notes="学生上传论文",httpMethod = "POST")
    @ApiImplicitParams(value ={
            @ApiImplicitParam(name = "stuId",value = "学生id",dataType = "String",paramType = "path"),
            @ApiImplicitParam(name = "grade",value = "成绩",dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "isPass",value = "是否通过",dataType = "Boolean",paramType = "query"),
    } )
    @RequestMapping({"/auditThesis/{stuId}"})
    User auditThesis(@PathVariable String stuId,@RequestParam("grade")String grade,@RequestParam("isPass")Boolean isPass) throws IOException {
        return userServicce.auditThesis(stuId,grade,isPass);
    }




}
